package com.d4a5.mapping.google2
{
	import com.d4a5.mapping.core.AmfObject;
	import com.d4a5.mapping.core.IAmfObject;
	import com.d4a5.mapping.core.IHighlightedObject;
	import com.d4a5.mapping.core.ISelectedObject;
	
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	
	
	public class wmgOverlayLayerBaseShape extends Sprite implements IAmfObject, IHighlightedObject, ISelectedObject
	{
		
		protected var _amf:AmfObject;
		protected var _highlighted:Boolean = false;
		protected var _highlightedChanged:Boolean = false;
		protected var _highlightable:Boolean = true;
		protected var _selected:Boolean = false;
		protected var _selectedChanged:Boolean = false;
		protected var _selectable:Boolean = true;
		
		protected var _repositionRequested:Boolean = false;
		protected var _redrawRequested:Boolean = false;
		
		protected var _matrix:Matrix;
		protected var _drawn:Boolean = false;
		protected var _options:Object;
		
		protected var _isAdded:Boolean = false;
		
		
		public function wmgOverlayLayerBaseShape( amf:AmfObject )
		{
			super();
			this._amf = amf;
			
			this.addEventListener(Event.ADDED,onAdded);

		}
		
		public static var labelAttribute:String = "label";
		
		override public function toString():String
		{
			return ( (this.attributes[wmgOverlayLayerBaseShape.labelAttribute]) ? this.attributes[wmgOverlayLayerBaseShape.labelAttribute] : super.toString());
			
		}
		
		public function get amf():AmfObject
		{
			return this._amf;
		}
		
		protected function updateAmf( amf:AmfObject ) : void {
			this._amf = amf;
			this.redraw();
		}
		
		public function generalizeAmf( coordsMatrix:Matrix , generalizePixelCount:uint = 2 ) : void {
			throw new IllegalOperationError( "Abstract Method: Must Override wmgOverlayLayerBaseShape.generalizeAmf" ); 
		}
		
		public function get attributes() : Object {
			return this._amf.attributes;
		}
		
		public function set attributes( value:Object ) : void {
			this._amf.attributes = value;
		}
		
		
		public function get highlighted():Boolean
		{
			return this._highlighted;
		}
		
		public function set highlighted(state:Boolean):void
		{
			if( this._highlightable && state != this._highlighted ){
				this._highlighted = state;
				if( this._highlightedChanged == false ){
					this._highlightedChanged = true;
					this.invalidateProperties();
				}
			}
		}
		
		public function get highlightable():Boolean
		{
			return this._highlightable;
		}
		
		public function set highlightable(state:Boolean):void
		{
			if( state != this._highlightable ){
				if( state == false ){
					this.highlighted = false;
					//this.removeEventListener(MouseEvent.MOUSE_MOVE,onRollOver);
					//this.removeEventListener(MouseEvent.ROLL_OUT,onRollOut);
				}
				//else{
					//this.addEventListener(MouseEvent.MOUSE_MOVE,onRollOver);
					//this.addEventListener(MouseEvent.ROLL_OUT,onRollOut);
				//}
				this._highlightable = state;
			}
		}
		
		//protected function onRollOver( event:Event ) : void {
		//	this.highlighted = true;
		//}
		//protected function onRollOut( event:Event ) : void {
		//	this.highlighted = false;
		//}
		
		
		public function get selected():Boolean
		{
			return this._selected;
		}
		
		public function set selected(state:Boolean):void
		{
			if( this._selectable && state != this._selected ){
				this._selected = state;
				if( this._selectedChanged == false ){
					this._selectedChanged = true;
					this.invalidateProperties();
				}
			}
		}
		
		public function get selectable():Boolean
		{
			return this._selectable;
		}
		
		public function set selectable(state:Boolean):void
		{
			if( state != this._selectable ){
				if( state == false ){
					this.selected = false;
					//this.removeEventListener(MouseEvent.CLICK,onClick);
				}
				//else{
					//this.addEventListener(MouseEvent.CLICK,onClick);
				//}
				this._selectable = state;
			}
		}
		
		//protected function onClick( event:Event ) : void {
		//	this.selected = !this.selected;
		//}
		
		public function invalidateProperties() : void {
			this.addEventListener(Event.ENTER_FRAME,onEnterFrameProperties);
		}
		
		protected function onEnterFrameProperties( event:Event ) : void {
			this.removeEventListener(Event.ENTER_FRAME,onEnterFrameProperties);
			this.commitProperties();
		}
		
		protected function commitProperties():void {
			if( this._highlightedChanged ){
				this._highlightedChanged = false;
				this.dispatchEvent( new Event( "highlighted_" + this._highlighted.toString() ) );
				this.redraw();
			}
			if( this._selectedChanged ){
				this._selectedChanged = false;
				this.dispatchEvent( new Event( "selected_" + this._selected.toString() ) );
				this.redraw();
			}
		}
		
		public function reposition( m:Matrix = null ) : void {
			this._matrix = (m) ? m : (this.parent as wmgOverlayLayer).getMatrix();
			
			//this._repositionRequested = true;
			//this.invalidateDisplayList();
			this.__reposition( this._matrix );
		}
		
		public function redraw( m:Matrix = null ) : void {
			this._matrix = (m) ? m : (this.parent as wmgOverlayLayer).getMatrix();
		
			//this._redrawRequested = true;
			//this.invalidateDisplayList();
			this.__redraw( this._matrix );
			this.__reposition( this._matrix );
		}
		
		
		public function invalidateDisplayList() : void {
			this.addEventListener(Event.ENTER_FRAME,onEnterFrameDisplayList);
		}
		
		protected function onEnterFrameDisplayList( event:Event ) : void {
			this.removeEventListener(Event.ENTER_FRAME,onEnterFrameDisplayList);
			this.updateDisplayList();
		}
		
		protected function updateDisplayList():void {	
			if( this._redrawRequested ){
				this._redrawRequested = false;
				this._repositionRequested = false;
				this.__redraw( this._matrix );
				this.__reposition( this._matrix );
			}
			else if( this._repositionRequested ){
				this._repositionRequested = false;
				this.__reposition( this._matrix );
			}
		}
		
		
		protected function onAdded( event:Event ) : void {
			this._isAdded = true;
			this.removeEventListener( Event.ADDED , onAdded );
			
			this._redrawRequested = true;
			this.invalidateDisplayList();
		}
		
		protected function __reposition( m:Matrix ) : void {
			if( this._amf && m ){
				if( this._drawn == false){
					this.__redraw( m );
				}
				
				var mapWidthPixels:Number = ( 1 << (wmgOverlayLayer.currentZoomLevel + 8) );
				
				this.y = m.ty;
				this.x =(this._amf.bounds.x.min > wmgOverlayLayer.currentMapBounds.x.max) 
					? m.tx - mapWidthPixels
					: ( this._amf.bounds.x.max < wmgOverlayLayer.currentMapBounds.x.min )
					? m.tx + mapWidthPixels
					: m.tx;					
				
			}
			else{
				this._drawn = false;
				this.graphics.clear();
				this.invalidateDisplayList();
			}		
		}
		protected function __redraw( m:Matrix ) : void {
			throw new IllegalOperationError( "Abstract Method: Must Override wmgOverlayLayerBaseShape.__redraw" ); 
		}
		
		public function setOptions( o:Object ) : void {
			throw new IllegalOperationError( "Abstract Method: Must Override wmgOverlayLayerBaseShape.setOptions" ); 
		}
		
		public function getOptions() : Object {
			//if( this.parent["renderer"] ){
			//	return this.parent["renderer"].getOptions( this , this._options );
			//}
			
			if( this.parent is wmgOverlayLayer ){
				return ( this.parent as wmgOverlayLayer ).optionsManager.getOptions( this );
			}
			return this.getDefaultOptions();
		}
		
		public function getDefaultOptions() : Object {
			throw new IllegalOperationError( "Abstract Method: Must Override wmgOverlayLayerBaseShape.getDefaultOptions" ); 
		}
		public function mergeOptions( toBeMerged:Array ) : Object {
			throw new IllegalOperationError( "Abstract Method: Must Override wmgOverlayLayerBaseShape.mergeOptions" ); 
		}
		
		public function updateGeometry( geom:Object ) : void {
			throw new IllegalOperationError( "Abstract Method: Must Override wmgOverlayLayerBaseShape.updateGeometry" ); 
		}
	}
}